package com.web3.management.repository;

import com.web3.management.entity.AccountConfig;
import com.web3.management.repository.projection.AccountTargetProjection;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

/**
 * 账号配置数据访问层
 *
 * @author Web3 Management Team
 */
@Repository
public interface AccountConfigRepository extends JpaRepository<AccountConfig, Integer> {

    /**
     * 根据账号ID查找配置
     *
     * @param accountId 账号ID
     * @return 配置列表
     */
    List<AccountConfig> findByAccountId(Integer accountId);

    /**
     * 根据账号ID分页查询配置
     *
     * @param accountId 账号ID
     * @param pageable  分页参数
     * @return 配置分页结果
     */
    Page<AccountConfig> findByAccountId(Integer accountId, Pageable pageable);

    /**
     * 根据账号ID和状态查询配置
     *
     * @param accountId 账号ID
     * @param status    状态
     * @param pageable  分页参数
     * @return 配置分页结果
     */
    Page<AccountConfig> findByAccountIdAndStatus(Integer accountId, Integer status, Pageable pageable);

    /**
     * 根据账号ID查找激活的配置
     *
     * @param accountId 账号ID
     * @return 激活的配置
     */
    Optional<AccountConfig> findByAccountIdAndIsActive(Integer accountId, Integer isActive);

    /**
     * 根据账号ID和配置名称查找配置
     *
     * @param accountId  账号ID
     * @param configName 配置名称
     * @return 配置信息
     */
    Optional<AccountConfig> findByAccountIdAndConfigName(Integer accountId, String configName);

    /**
     * 检查账号是否有配置
     *
     * @param accountId 账号ID
     * @return 是否有配置
     */
    boolean existsByAccountId(Integer accountId);

    /**
     * 检查账号配置名称是否存在
     *
     * @param accountId  账号ID
     * @param configName 配置名称
     * @return 是否存在
     */
    boolean existsByAccountIdAndConfigName(Integer accountId, String configName);

    /**
     * 检查账号配置名称是否存在（排除指定ID）
     *
     * @param accountId  账号ID
     * @param configName 配置名称
     * @param id         排除的ID
     * @return 是否存在
     */
    @Query("SELECT COUNT(ac) > 0 FROM AccountConfig ac WHERE ac.accountId = :accountId AND ac.configName = :configName AND ac.id != :id")
    boolean existsByAccountIdAndConfigNameAndIdNot(@Param("accountId") Integer accountId,
                                                   @Param("configName") String configName,
                                                   @Param("id") Integer id);

    /**
     * 停用指定账号的所有配置
     *
     * @param accountId 账号ID
     */
    @Modifying
    @Transactional
    @Query("UPDATE AccountConfig ac SET ac.isActive = 0 WHERE ac.accountId = :accountId")
    void deactivateAllAccountConfigs(@Param("accountId") Integer accountId);

    /**
     * 激活指定账号配置并停用该账号的其他配置
     *
     * @param accountId 账号ID
     * @param configId  要激活的配置ID
     */
    @Modifying
    @Transactional
    @Query("UPDATE AccountConfig ac SET ac.isActive = CASE WHEN ac.id = :configId THEN 1 ELSE 0 END WHERE ac.accountId = :accountId")
    void activateAccountConfigAndDeactivateOthers(@Param("accountId") Integer accountId,
                                                  @Param("configId") Integer configId);

    /**
     * 统计指定账号的配置数量
     *
     * @param accountId 账号ID
     * @return 配置数量
     */
    long countByAccountId(Integer accountId);

    /**
     * 统计指定账号激活配置数量
     *
     * @param accountId 账号ID
     * @param isActive  是否激活
     * @return 配置数量
     */
    long countByAccountIdAndIsActive(Integer accountId, Integer isActive);

    /**
     * 统计所有账号配置数量
     *
     * @return 总配置数量
     */
    @Query("SELECT COUNT(ac) FROM AccountConfig ac")
    long countAllAccountConfigs();

    /**
     * 统计激活的账号配置数量
     *
     * @param isActive 是否激活
     * @return 配置数量
     */
    long countByIsActive(Integer isActive);

    /**
     * 根据项目名称查找配置
     *
     * @param projectName 项目名称
     * @return 配置列表
     */
    List<AccountConfig> findByProjectName(String projectName);

    /**
     * 删除指定账号的所有配置
     *
     * @param accountId 账号ID
     */
    @Modifying
    @Transactional
    void deleteByAccountId(Integer accountId);

    /**
     * 统计所有激活且有效的账号配置目标交易额之和
     *
     * @return 目标交易额合计
     */
    @Query("SELECT COALESCE(SUM(COALESCE(ac.targetBuyQuote, 0)), 0) FROM AccountConfig ac WHERE ac.isActive = 1 AND ac.status = 1")
    BigDecimal sumActiveTargetBuyQuote();

    /**
     * 获取所有账号的目标交易额
     */
    @Query("SELECT ac.accountId AS accountId, COALESCE(SUM(COALESCE(ac.targetBuyQuote, 0)), 0) AS targetAmount " +
            "FROM AccountConfig ac WHERE ac.isActive = 1 AND ac.status = 1 GROUP BY ac.accountId")
    List<AccountTargetProjection> sumActiveTargetBuyQuoteGroupByAccount();
}
